feat: implement bet slip summary, oracle circuit breaker, and dispute UI#646
Open
Fahmedo wants to merge 318 commits intoHahfyeex:mainfrom
Open
feat: implement bet slip summary, oracle circuit breaker, and dispute UI#646Fahmedo wants to merge 318 commits intoHahfyeex:mainfrom
Fahmedo wants to merge 318 commits intoHahfyeex:mainfrom
Conversation
…launch feat: implement permissionless market creation with automated validation
…ss-test test: add Taurus throughput stress test suite with CI integration
…hanism feat: implement Dispute & Bond mechanism in Soroban contract
feat: Implement WebSocket odds streaming and new image routes.
…-analytics feat: implement 'Wisdom of the Crowd' analytics engine
… data and cursor-based pagination (Hahfyeex#160)
…roduce a worker to consume these events, and update .gitignore. (Hahfyeex#157)
…Hahfyeex#168) - Add vault storage keys to DataKey enum: * VaultBalance: tracks total swept funds in Instance storage * ClaimDeadline(u64): records resolution timestamp per market * OriginalPayouts(u64): stores exact payout amounts for claimants * MarketSwept(u64): prevents double-sweeping - Implement sweep_unclaimed(market_id) function: * Callable only after 30 days (2,592,000 seconds) post-resolution * Checks each bet in market for unclaimed payouts * Respects settlement cursor (only sweeps unpaid winners) * Moves unclaimed funds to vault balance * Stores original payout amounts for future claims * Marks market as swept to prevent double-sweeping * Returns amount swept - Implement invest_vault() function: * Admin-only function for AMM re-investment * Placeholder for Stellar AMM integration * Validates vault has funds before investment * Returns amount invested * TODO: Actual AMM swap/deposit operations - Implement claim_original(market_id, claimant) function: * Allows winners to claim exact original payout anytime * Works even after vault sweep * Pays from vault balance if market swept * Prevents double-claiming by zeroing payout * Requires claimant authentication * Returns amount claimed - Add vault query functions: * get_vault_balance(): returns current vault balance * get_claim_deadline(market_id): returns resolution timestamp * is_market_swept(market_id): checks if market swept * get_original_payout(market_id, address): gets claimant's amount - Update resolve_market() to record claim deadline: * Stores resolution timestamp for 30-day tracking * Enables sweep_unclaimed deadline validation - Add comprehensive unit tests (30+ test cases): * Claim deadline recording on resolution * Vault balance initialization and tracking * 30-day deadline enforcement (before/at/after) * Sweep with various winner counts (0, 3, 5) * Settlement cursor respect (partial payments) * Double-sweep prevention * Original payout storage and retrieval * Claim after sweep functionality * Double-claim prevention * Multiple winners claiming * Vault balance decrease on claims * invest_vault validation * Edge cases: unresolved markets, non-winners, empty vault Test coverage: - Sweep logic: 10+ tests covering all scenarios - Claim logic: 8+ tests covering claim flows - Vault operations: 5+ tests for vault management - Edge cases: 7+ tests for error conditions - Total: 30+ tests achieving >90% coverage target Vault mechanics: - 30-day claim window before sweep eligibility - Original payouts tracked separately from yield - Claimants always get exact original amount - Vault balance managed independently - Settlement cursor respected (no double-payment) - Admin-controlled sweep and investment Security features: - Admin-only sweep and invest operations - Claimant authentication required for claims - Double-sweep prevention via MarketSwept flag - Double-claim prevention via payout zeroing - Vault balance validation before claims - 30-day deadline strictly enforced AMM integration (placeholder): - invest_vault() validates vault balance - TODO: Stellar AMM deposit operations - TODO: LP token tracking - TODO: Yield monitoring - Production implementation requires AMM client Inline documentation: - Comprehensive function comments - Vault re-balancing logic explained - Claimant protection mechanisms documented - AMM integration strategy outlined - 30-day deadline rationale provided - Storage key purposes clarified Closes Hahfyeex#162
…ahfyeex#105) - Add MarketStatus enum (Open, Locked, Proposed, Resolved) - Add proposed_outcome and proposal_timestamp fields to Market struct - Add propose_result() with oracle auth and Locked state guard - Refactor resolve_market() with Proposed guard and 24h liveness window - Add lock_market() helper (Open -> Locked) - Add LIVENESS_WINDOW constant (86400s) - Add 10 tests covering state transitions, auth, and liveness boundary - Add docs/resolution-flow.md
…x#107) * feat: implement Proposed outcome state machine (Issue Hahfyeex#24) - Add MarketStatus enum (Open, Locked, Proposed, Resolved) - Add proposed_outcome and proposal_timestamp fields to Market struct - Add propose_result() with oracle auth and Locked state guard - Refactor resolve_market() with Proposed guard and 24h liveness window - Add lock_market() helper (Open -> Locked) - Add LIVENESS_WINDOW constant (86400s) - Add 10 tests covering state transitions, auth, and liveness boundary - Add docs/resolution-flow.md * feat: implement Role-Based Access Control (Issue Hahfyeex#14) - Add access.rs: Role enum (Admin, Oracle, Resolver), ContractError, check_role/get_role/set_role helpers using persistent storage - Wire RBAC into all gated functions: Admin: initialize, assign_role, pause, set_market_params, create_market, lock_market Oracle: propose_result Resolver: resolve_market - Add assign_role() for admin-authorized key rotation - Add pause()/unpause() with assert_not_paused guard - Add set_market_params() for Admin to update Open market params - Remove single-admin DataKey::Admin and DataKey::OracleAddress in favour of persistent Role storage - Add 14 tests covering RBAC, pause, state machine, and boundaries - Add SECURITY.md with role hierarchy and function-role mapping * feat: implement emergency stop circuit breaker (Issue Hahfyeex#10) - Rename DataKey::Paused -> DataKey::IsPaused (persistent storage) - Add set_pause(admin, paused): admin-verified toggle with ContractPauseToggled event - Add panic_if_paused(): panics with exact message 'ContractPaused' - Add is_paused() -> bool: read-only query for frontend visibility - Add withdraw(): bettor stake withdrawal, gated by panic_if_paused - Gate place_bet and withdraw with panic_if_paused at function entry - Migrate IsPaused to persistent storage (survives ledger archival) - Add 8 circuit-breaker tests: toggle, non-admin rejection, normal ops, ContractPaused panics for place_bet and withdraw, event emission - Update README.md with Security Operations section
…x#170) - Refactor Map<Address, (u32, i128)> to Vec<(Address, u32, i128)> for user positions - Remove Map import from soroban_sdk (no longer needed) Gas optimization rationale: - Map uses expensive key hashing operations for every access - Vec uses sequential access which is cheaper for small datasets - Typical prediction markets have <100 bettors - For n<100, Vec O(n) linear scan is faster than Map O(1) with hashing overhead - Estimated 30% gas cost reduction for typical market operations Functions refactored: 1. create_market(): Initialize positions as Vec instead of Map 2. place_bet(): Linear scan to find/update bettor position 3. batch_distribute(): Iterate through Vec instead of Map Storage pattern changes: - Before: Map<Address, (u32, i128)> - expensive hashing per operation - After: Vec<(Address, u32, i128)> - sequential access, no hashing Performance characteristics: - place_bet: O(n) scan vs O(1) Map.set, but cheaper for n<100 - batch_distribute: O(n) iteration vs O(n) Map.iter, but no hashing overhead - Memory: Vec is more compact than Map (no hash table overhead) Inline documentation: - Added gas optimization comments to all refactored functions - Explained Vec vs Map tradeoffs - Documented typical market size assumptions - Clarified performance characteristics All existing tests pass with Vec-based storage: - Market creation and initialization - Bet placement and position updates - Batch distribution and settlement - Edge cases and error conditions No behavioral changes: - Same functionality, different storage implementation - All assertions and validations unchanged - Event emissions unchanged - Settlement logic unchanged Closes Hahfyeex#156
* feat: implement Proposed outcome state machine (Issue Hahfyeex#24) - Add MarketStatus enum (Open, Locked, Proposed, Resolved) - Add proposed_outcome and proposal_timestamp fields to Market struct - Add propose_result() with oracle auth and Locked state guard - Refactor resolve_market() with Proposed guard and 24h liveness window - Add lock_market() helper (Open -> Locked) - Add LIVENESS_WINDOW constant (86400s) - Add 10 tests covering state transitions, auth, and liveness boundary - Add docs/resolution-flow.md * feat: implement Role-Based Access Control (Issue Hahfyeex#14) - Add access.rs: Role enum (Admin, Oracle, Resolver), ContractError, check_role/get_role/set_role helpers using persistent storage - Wire RBAC into all gated functions: Admin: initialize, assign_role, pause, set_market_params, create_market, lock_market Oracle: propose_result Resolver: resolve_market - Add assign_role() for admin-authorized key rotation - Add pause()/unpause() with assert_not_paused guard - Add set_market_params() for Admin to update Open market params - Remove single-admin DataKey::Admin and DataKey::OracleAddress in favour of persistent Role storage - Add 14 tests covering RBAC, pause, state machine, and boundaries - Add SECURITY.md with role hierarchy and function-role mapping
* feat: implement Proposed outcome state machine (Issue Hahfyeex#24) - Add MarketStatus enum (Open, Locked, Proposed, Resolved) - Add proposed_outcome and proposal_timestamp fields to Market struct - Add propose_result() with oracle auth and Locked state guard - Refactor resolve_market() with Proposed guard and 24h liveness window - Add lock_market() helper (Open -> Locked) - Add LIVENESS_WINDOW constant (86400s) - Add 10 tests covering state transitions, auth, and liveness boundary - Add docs/resolution-flow.md * feat: implement Role-Based Access Control (Issue Hahfyeex#14) - Add access.rs: Role enum (Admin, Oracle, Resolver), ContractError, check_role/get_role/set_role helpers using persistent storage - Wire RBAC into all gated functions: Admin: initialize, assign_role, pause, set_market_params, create_market, lock_market Oracle: propose_result Resolver: resolve_market - Add assign_role() for admin-authorized key rotation - Add pause()/unpause() with assert_not_paused guard - Add set_market_params() for Admin to update Open market params - Remove single-admin DataKey::Admin and DataKey::OracleAddress in favour of persistent Role storage - Add 14 tests covering RBAC, pause, state machine, and boundaries - Add SECURITY.md with role hierarchy and function-role mapping * feat: implement emergency stop circuit breaker (Issue Hahfyeex#10) - Rename DataKey::Paused -> DataKey::IsPaused (persistent storage) - Add set_pause(admin, paused): admin-verified toggle with ContractPauseToggled event - Add panic_if_paused(): panics with exact message 'ContractPaused' - Add is_paused() -> bool: read-only query for frontend visibility - Add withdraw(): bettor stake withdrawal, gated by panic_if_paused - Gate place_bet and withdraw with panic_if_paused at function entry - Migrate IsPaused to persistent storage (survives ledger archival) - Add 8 circuit-breaker tests: toggle, non-admin rejection, normal ops, ContractPaused panics for place_bet and withdraw, event emission - Update README.md with Security Operations section * feat: admin circuit breaker toggle_pause (Issue Hahfyeex#6) - Rename set_pause -> toggle_pause(admin, setup_pause) per spec - Rename PauseToggled event symbol to match spec - All circuit breaker logic already in place from Issue Hahfyeex#10: DataKey::IsPaused in persistent storage panic_if_paused() panics with 'ContractPaused' is_paused() read-only query place_bet and withdraw gated by panic_if_paused Full test suite: toggle, non-admin rejection, normal ops, panic cases
…cle statistics, and dedicated truth and whale watcher workers. (Hahfyeex#173) Co-authored-by: folex1275 <soleyefolarin@gmail.com>
…ex#176) * feat: implement Firebase App Check for API protection (Hahfyeex#62) * feat: add Semgrep + secret scanning CI pipeline for security --------- Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com>
…ahfyeex#175) * feat: implement Firebase App Check for API protection (Hahfyeex#62) * feat: add Semgrep + secret scanning CI pipeline for security --------- Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com>
* feat: add WhatIfSimulator P&L projection panel
- Add collapsible WhatIfSimulator component with Recharts BarChart
- Stake input via range slider and number field kept in sync
- Real-time updates via useEffect with 200ms debounce
- Shows projected payout, P&L, and implied probability
- Pure calc utility in simulatorCalc.ts with full inline docs
- 100% test coverage on calculation logic (36 tests passing)
- Integrated into MarketCard (desktop) and TradeDrawer (mobile)
- README documents P&L formula and usage
* feat: add BettingSlip batch betting drawer
- BettingSlipContext: global queue state with addBet/removeBet/clearBets
- WalletContext: lifts wallet state globally for layout-level access
- useBatchTransaction: bundles bets into single Freighter XDR approval
- BettingSlip: slide-up drawer (mobile) / fixed right panel (desktop)
- Toast: queue-full warning when 6th bet attempted (max 5)
- MarketCard: Add to Slip button alongside existing Bet button
- layout.tsx: providers + BettingSlipWrapper mounted globally
- page.tsx: migrated to useWalletContext
- README: documents component usage, props, and batch flow
* feat: add PoolOwnershipChart fractional ownership pie chart
- poolOwnership.ts: pure transform — group bets by wallet, calc % share,
group wallets below 1% into Others slice, with full inline comments
- usePoolOwnership: fetches GET /api/markets/:id, subscribes to Socket.io
oddsUpdate events and re-renders chart live on new bets
- PoolOwnershipChart: Recharts PieChart with custom tooltip (wallet + XLM),
design token slice colors, loading/error/empty states
- MarketCard: PoolOwnershipChart mounted below pool info line
- socket.io-client installed for live WebSocket updates
- Unit tests for buildOwnershipSlices and abbreviateWallet (>90% coverage)
- README documents API data structure and transformation pipeline
* feat: add useFormPersistence hook for bet form state
- useFormPersistence(marketId): persists outcomeIndex, amount, slippageTolerance
to localStorage key stella_bet_form_{marketId}
- Restores state on mount, re-hydrates when marketId changes
- clearForm(): removes localStorage entry and resets fields to defaults
- 300ms debounced writes to avoid thrashing on every keystroke
- MarketCard: wired to persistence hook, clearForm on submit, slippage selector
- TradeDrawer: wired to persistence hook, clearForm on submit, slippage selector
- Both components have Clear form button for manual reset
- Unit tests for storageKey, read/write/clear, and round-trip (>90% coverage)
- README documents key format and how to clear state for testing
---------
Co-authored-by: victorisiguzor874 <jamesberry87487.com>
* feat: add WhatIfSimulator P&L projection panel - Add collapsible WhatIfSimulator component with Recharts BarChart - Stake input via range slider and number field kept in sync - Real-time updates via useEffect with 200ms debounce - Shows projected payout, P&L, and implied probability - Pure calc utility in simulatorCalc.ts with full inline docs - 100% test coverage on calculation logic (36 tests passing) - Integrated into MarketCard (desktop) and TradeDrawer (mobile) - README documents P&L formula and usage * feat: add BettingSlip batch betting drawer - BettingSlipContext: global queue state with addBet/removeBet/clearBets - WalletContext: lifts wallet state globally for layout-level access - useBatchTransaction: bundles bets into single Freighter XDR approval - BettingSlip: slide-up drawer (mobile) / fixed right panel (desktop) - Toast: queue-full warning when 6th bet attempted (max 5) - MarketCard: Add to Slip button alongside existing Bet button - layout.tsx: providers + BettingSlipWrapper mounted globally - page.tsx: migrated to useWalletContext - README: documents component usage, props, and batch flow * feat: add PoolOwnershipChart fractional ownership pie chart - poolOwnership.ts: pure transform — group bets by wallet, calc % share, group wallets below 1% into Others slice, with full inline comments - usePoolOwnership: fetches GET /api/markets/:id, subscribes to Socket.io oddsUpdate events and re-renders chart live on new bets - PoolOwnershipChart: Recharts PieChart with custom tooltip (wallet + XLM), design token slice colors, loading/error/empty states - MarketCard: PoolOwnershipChart mounted below pool info line - socket.io-client installed for live WebSocket updates - Unit tests for buildOwnershipSlices and abbreviateWallet (>90% coverage) - README documents API data structure and transformation pipeline --------- Co-authored-by: victorisiguzor874 <jamesberry87487.com> Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com>
Hahfyeex#183) - Add FeeMode enum (Burn / Treasury) and DataKey variants CreationFee, FeeDestination, FeeModeConfig to contract storage - Add creator: Address param to create_market; charge fee via try_transfer before market is stored; abort with InsufficientFeeBalance on failure - Add update_fee(new_fee, new_destination, new_mode) admin function with admin auth guard — no redeployment needed to change fee config - Add get_fee_config() read-only helper returning (fee, dest, mode) - Emit FeeColl event on every successful fee collection for off-chain indexing - Add 7 unit tests covering: zero-fee, treasury routing, burn routing, insufficient balance abort, max fee, admin auth enforcement, fee reset - Add CREATION_FEE_README.md documenting parameters and DAO governance - Update README.md to reference creation fee and DAO governance docs Closes Hahfyeex#147
* feat: implement Firebase App Check for API protection (Hahfyeex#62) * feat: add Semgrep + secret scanning CI pipeline for security * feat: implement SEP-0157 contract source attestation workflow (Hahfyeex#65) --------- Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com>
* feat: add WhatIfSimulator P&L projection panel - Add collapsible WhatIfSimulator component with Recharts BarChart - Stake input via range slider and number field kept in sync - Real-time updates via useEffect with 200ms debounce - Shows projected payout, P&L, and implied probability - Pure calc utility in simulatorCalc.ts with full inline docs - 100% test coverage on calculation logic (36 tests passing) - Integrated into MarketCard (desktop) and TradeDrawer (mobile) - README documents P&L formula and usage * feat: add BettingSlip batch betting drawer - BettingSlipContext: global queue state with addBet/removeBet/clearBets - WalletContext: lifts wallet state globally for layout-level access - useBatchTransaction: bundles bets into single Freighter XDR approval - BettingSlip: slide-up drawer (mobile) / fixed right panel (desktop) - Toast: queue-full warning when 6th bet attempted (max 5) - MarketCard: Add to Slip button alongside existing Bet button - layout.tsx: providers + BettingSlipWrapper mounted globally - page.tsx: migrated to useWalletContext - README: documents component usage, props, and batch flow --------- Co-authored-by: victorisiguzor874 <jamesberry87487.com>
- Add collapsible WhatIfSimulator component with Recharts BarChart - Stake input via range slider and number field kept in sync - Real-time updates via useEffect with 200ms debounce - Shows projected payout, P&L, and implied probability - Pure calc utility in simulatorCalc.ts with full inline docs - 100% test coverage on calculation logic (36 tests passing) - Integrated into MarketCard (desktop) and TradeDrawer (mobile) - README documents P&L formula and usage Co-authored-by: victorisiguzor874 <jamesberry87487.com>
Co-authored-by: Your Name <your-email@example.com>
* implementing the task * implementing the component * implementing the component * chore: add issue creation script for all 40 backlog issues * chore: add issue body files and Python patch script * feat: implement Go ledger event scraper with goroutine parallelism (Hahfyeex#190) Add independent Go service that scrapes Stellar ledger events: - Main loop iterating ledger sequences via Horizon API - Filter operations by contract address - Goroutine worker pool (10 concurrent) with sync.WaitGroup - PostgreSQL storage for archived events - Catch-up mode via --start-ledger CLI flag - Resume from last processed ledger on restart - 7 unit tests covering filtering, concurrency, catch-up, and resume Closes Hahfyeex#151 * feat: implement immutable audit logging with IPFS and on-chain hashes (Hahfyeex#189) Backend: - AuditLogger service: serialize entries to JSON, pin to IPFS via Pinata - Non-blocking: IPFS failures logged but don't break operations - GET /api/audit-logs and GET /api/audit-logs/:id endpoints - POST /api/audit-logs to create entries - DB migration for audit_logs table Contract: - store_audit_hash — admin stores IPFS CID hash on-chain - get_audit_hash / get_audit_log_count — retrieve stored hashes - Verification: fetch CID from chain, retrieve from IPFS, confirm match Frontend: - AuditLogViewer component with table display and IPFS links Closes Hahfyeex#153 * feat: add market share URI shortener (Hahfyeex#187) Add lightweight short URL service for social sharing: - POST /api/short-url — generate 6-char short code for a market - GET /s/:code — 301 redirect to full market URL - GET /api/short-url/:code — get short URL info Uses safe alphabet (excludes 0,O,I,l), rejects offensive patterns. Includes DB migration and 16 tests with 100% coverage on hashing and redirection logic. Closes Hahfyeex#34 * Hahfyeex#129 [FE] Hahfyeex#139 - IPFS Resolver --------- Co-authored-by: nafiuishaaq <nafiuig@gmail.com> Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com> Co-authored-by: hahfyeez <tunmisehassan@gmail.com> Co-authored-by: Akpolo Ogagaoghene Prince <104951733+ogazboiz@users.noreply.github.com>
… and frontend (Hahfyeex#261) Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com>
…ahfyeex#114) Implement WhitelistedTokens storage in the Soroban smart contract so that only approved tokens (e.g. XLM, USDC, ARST) can be used as collateral for prediction-market bets. Contract changes (contracts/prediction_market/src/lib.rs): - Add WhitelistedTokens variant to DataKey enum - Initialize empty whitelist on contract init - Add admin-only add/remove/query/check functions for the whitelist - Enforce whitelist in create_market (reject non-whitelisted tokens) - Enforce whitelist in place_bet (reject bets after token delisting) - Add 12 comprehensive tests covering all whitelist paths, including rejection with de-listed tokens and visual-validation logging Backend changes: - Add whitelisted_tokens DB table with migration (002) - Add token whitelist check in POST /api/bets before accepting a bet - Add /api/whitelisted-tokens CRUD routes for admin management - Add 18 unit tests for whitelist validation logic Note: cargo clippy skipped due to pre-existing Rust toolchain incompatibility (1.79.0 vs base64ct edition2024 requirement). Closes Hahfyeex#16 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com>
* feat: Implement Dynamic Market Detail Page (Hahfyeex#12) * feat(contracts): Automated Market Settlement Logic (Hahfyeex#11)
* feat: implement market creation fee with DAO treasury transfer * feat: implement bet volume analytics endpoints with Redis caching --------- Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com>
- Migration 011: add cancelled_at and grace_period_ends_at to bets - POST /api/bets: sets grace_period_ends_at on insert (default 5 min, configurable via BET_GRACE_PERIOD_SECONDS) - DELETE /api/bets/:id: cancel bet within grace period, refunds pool, invalidates portfolio cache - Unit tests covering all cancellation guard cases and happy path
…nt (Hahfyeex#563) - Add migration 010 for market_resolution_history table - Record history on PROPOSED, CONFIRMED, REJECTED, DISPUTED state changes - Add POST /:id/confirm, /:id/reject, /:id/dispute routes - Add public GET /:id/history endpoint with abbreviated wallet and action labels - Add unit tests for all state changes and history endpoint
* fix: add non-blocking error handling to triggerNotification utility * feat: implement market category taxonomy and filtering system
…ahfyeex#169) Co-authored-by: Shantel Peters <shantelpeters@example.com> Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com>
* feat: implement advanced odds chart with time range controls and crosshair tooltip * good
* feat: implement Stellar SEP-10 Web Authentication for JWT issuance * staged
Co-authored-by: blackghost <blackghost@example.com>
* implementing the task * implementing the component * implementing the component * feat: implement immutable audit logging with IPFS and on-chain hashes (Hahfyeex#189) Backend: - AuditLogger service: serialize entries to JSON, pin to IPFS via Pinata - Non-blocking: IPFS failures logged but don't break operations - GET /api/audit-logs and GET /api/audit-logs/:id endpoints - POST /api/audit-logs to create entries - DB migration for audit_logs table Contract: - store_audit_hash — admin stores IPFS CID hash on-chain - get_audit_hash / get_audit_log_count — retrieve stored hashes - Verification: fetch CID from chain, retrieve from IPFS, confirm match Frontend: - AuditLogViewer component with table display and IPFS links Closes Hahfyeex#153 * Uisocalflow * Uistellaroracle * feat: Implement automated Soroban WASM build & lint CI (Hahfyeex#63) - Add comprehensive GitHub Actions workflow for Soroban contracts - Enforce cargo fmt --check and cargo clippy -- -D warnings - Validate WASM size constraint (64KB Soroban limit) - Pin Rust toolchain to 1.79.0 for consistency - Add Justfile for convenient local development commands - Implement parallel CI jobs for faster execution CI Jobs: - rust-checks: Format and lint verification - build-wasm: Build and validate WASM size - run-tests: Execute unit and integration tests - security-audit: Dependency and unsafe code checks - ci-summary: Aggregate results and generate report Features: - Treats all Clippy warnings as errors (-D warnings) - Generates detailed job summaries with WASM metrics - Uploads WASM artifacts for download - Caches Rust toolchain and dependencies for speed - Path-based triggering (only runs on contract changes) Documentation: - SOROBAN_CI_README.md: Comprehensive guide (500+ lines) - SOROBAN_CI_QUICK_REFERENCE.md: Quick command reference - SOROBAN_CI_CHECKLIST.md: Implementation checklist - Rust toolchain version: 1.79.0 - Soroban SDK version: 21.7.6 Closes Hahfyeex#63 * docs: Add CI implementation summary * feat: Implement Firebase Firestore live comments (Hahfyeex#61) - Add real-time comment system for market discussions - Implement cursor-based pagination (10 comments per page) - Create comprehensive Firestore security rules with 95%+ test coverage - Add MarketComments component with instant sync across clients - Include character counter, relative timestamps, and wallet truncation - Implement identity verification (users can only post as themselves) - Add 27 security rules tests covering all operations - Create comprehensive documentation and setup guides Features: - Real-time synchronization with onSnapshot listener - Pagination with 'Load more' button - Character limit (500 chars) with counter - Relative timestamps (2m ago, 3h ago, etc.) - Wallet address truncation and avatars - Loading states and error handling - Security rules prevent spoofing and validate all fields Closes Hahfyeex#61 * docs: Add final implementation summary * feat: implement 5 critical error states and Empty Ledger UX Hahfyeex#86 * Uistellarasset * feat: Implement Liquidity Provider (LP) Dashboard UI (Hahfyeex#90) - Create comprehensive LP Dashboard with 7 React components - Implement Current APY, Total Fees Earned, and Impermanent Loss Warning displays - Add high-contrast Deposit XLM/USDC and Withdraw interfaces - Include Risk Level indicators (Low/Medium/High) for each pool - Add Stellar Low Fee tooltips highlighting rebalancing advantages - Implement visual separation between Earning and Betting charts - Create Active LP Positions view with portfolio summary Components: - LPDashboard: Main container with tab navigation - LPMetricsOverview: 4 key metrics cards - LPPositionsView: Active positions list with portfolio summary - LPEarningsChart: Analytics with earning vs betting explanation - LPDepositModal: Deposit interface with real-time estimates - LPWithdrawModal: Withdraw interface with percentage slider Features: - Risk indicators on every pool (color-coded badges) - Real-time APY and fee calculations - Impermanent loss warnings for medium/high risk pools - Stellar low fee highlights (~$0.00001 vs $5-50 on Ethereum) - Prominent earning vs betting education banner - Responsive design (mobile, tablet, desktop) - Full TypeScript type safety - Comprehensive error handling Documentation: - LP_DASHBOARD_README.md: Complete design specifications - LP_DASHBOARD_IMPLEMENTATION.md: Integration guide - LP_DASHBOARD_CHECKLIST.md: Implementation checklist - Design system fully documented - API endpoints defined - User flows documented Closes Hahfyeex#90 * docs: Add LP Dashboard implementation summary * feat(contracts): optimized ledger footprint via Instance storage - Move total_shares (was TotalPool) to Instance storage — hot path on every place_bet - Move is_paused to Instance storage — checked on every place_bet - Keep UserPosition (was Bets) and Market metadata in Persistent storage - Add set_paused/get_is_paused/get_total_shares public helpers - Rename Bets → UserPosition, TotalPool → TotalShares for clarity - Add 21 tests covering storage consistency, pause logic, edge cases - Add STORAGE_OPTIMIZATION.md with XLM savings breakdown Reduces place_bet ledger footprint by 2 reads + 2 writes per call (~67% fee reduction). * feat(contracts): batch-transfer settlement with cursor pagination - Add batch_distribute(market_id, batch_size) — pays up to batch_size winners per tx, advances SettlementCursor in Instance storage - Enforce MAX_BATCH_SIZE=25 to stay well under Soroban 100M instruction ceiling - distribute_rewards becomes a thin wrapper over batch_distribute(MAX_BATCH_SIZE) - Add get_settlement_cursor() for callers to track paging progress - Add SettlementCursor to DataKey enum (Instance storage — hot write) - 30 tests: cursor advancement, partial batches, idempotency, guard panics, gas comparison baseline (10 individual vs 2 batches of 5) - Add BATCH_SETTLEMENT_README.md with cost table and batch_size CPU math * feat: integrate Firebase Analytics for user behavior tracking - Add Firebase Analytics modular SDK with privacy compliance - Implement begin_checkout event tracking for bet modal opens - Add share_market event with native share API and clipboard fallback - Track help_doc_read events from navigation help button - Monitor slippage_changed events on transaction failures - Add bet_placed and bet_error tracking for conversion insights - Ensure privacy with anonymous session IDs (no wallet addresses) - Create comprehensive ANALYTICS_EVENTS.md documentation - Fix TypeScript typing for Firebase Messaging export PR Acceptance Criteria: ✅ Uses firebase/analytics modular SDK for small bundle size ✅ Mini-README lists top 5 custom events being tracked ✅ Privacy compliant - no PII, anonymous session IDs only * feat: Add automated PostgreSQL backup service with S3 integration - Implement pg_dump-based backup script with S3 upload - Add AES256 encryption for secure storage - Create restore script with point-in-time recovery - Set up 6-hour automated backup schedule via cron - Maintain 24-hour recovery window (4 backups) - Add comprehensive testing and documentation - Include step-by-step recovery guide for emergency situations Addresses requirement for 24-hour recovery plan for Market Descriptions and Social Data. * feat(contracts): graceful shutdown via GlobalStatus flag - Add GlobalStatus to DataKey enum (Instance storage, default true) - set_global_status(active) — admin-only, single Instance write - get_global_status() — public read - create_market checks GlobalStatus, panics with 'Platform is shut down' if false - place_bet, resolve_market, batch_distribute unaffected — existing markets continue to resolve and pay out normally during shutdown - Initialize sets GlobalStatus=true on first deploy - 6 new tests: default active, create blocked, place_bet/resolve/distribute allowed, re-activation restores create_market (36 total) - Add GRACEFUL_SHUTDOWN_README.md explaining soft vs hard pause tradeoffs * Add Landing Page - Designed a high-fidelity landing page focused on the hero section - Combined Polymarket-style layout with Stellar-inspired branding - Considered usability, visual hierarchy, and mobile responsiveness - Included design rationale in README.md * Add README for Stellar PolyMarket landing page design This README outlines the design for a high-fidelity landing page for Stellar PolyMarket, detailing the approach, key decisions, and responsiveness. * Add Landing Page Design - Designed a high-fidelity landing page focused on the hero section - Combined Polymarket-style layout with Stellar-inspired branding - Considered usability, visual hierarchy, and mobile responsiveness - Included design rationale in README.md * Delete Mobile LIght Mode.jpg * Delete Mobile Dark Mode.jpg * Delete Stella Polymarket Landing Page D.jpg * Delete Stella Polymarket Landing Page L.jpg * Rename Stella Polymarket Landing Page D.png to designs/landing-page.png * Rename landing-page.png to landing-page-dark.png * Rename Stella Polymarket Landing Page L.png to designs/landing-page-light.png * Rename Mobile Dark Mode.png to designs/responsive-mobile-dark.png * Rename Mobile LIght Mode.png to designs/responsive-mobile-light.png * Create Figma Landing Page Screens * Rename designs/README.md to designs/UI Design/README.md * Rename designs/landing-page-dark.png to designs/UI Design/landing-page-dark.png * Rename designs/landing-page-light.png to designs/UI Design/landing-page-light.png * Rename designs/responsive-mobile-dark.png to designs/UI Design/responsive-mobile-dark.png * Rename designs/responsive-mobile-light.png to designs/UI Design/responsive-mobile-light.png * Create Figma Design Screens * Rename designs/UI Design/Figma Design Screens to UI Design/Figma Design Screens * Rename designs/UI Design/README.md to UI Design/README.md * Rename designs/UI Design/landing-page-light.png to UI Design/Landing-page-light.png * Rename designs/UI Design/landing-page-dark.png to UI Design/Landing-page-dark.png * Rename designs/UI Design/responsive-mobile-light.png to UI Design/responsive-mobile-light.png * Rename designs/UI Design/responsive-mobile-dark.png to UI Design/responsive-mobile-dark.png * Add files via upload * feat: implement paginated 'My Positions' endpoint with joined markets data and cursor-based pagination * feat: implement Soroban TTL extension logic and maintenance worker script * feat: implement Dispute & Bond mechanism in Soroban contract with MarketStatus state machine * Add files via upload * feat: implement permissionless market creation with automated validation - Implement comprehensive validation middleware with 4 rules: * Description length: minimum 50 characters for context * Outcome count: 2-5 outcomes (binary or multi-choice) * End date: must be future date within 1 year * Duplicate check: case-insensitive unique question validation - Add Redis-based rate limiting: * 3 markets per wallet per 24 hours * Distributed rate limiting with automatic TTL * Specific error codes with retry-after headers * Graceful fallback if Redis unavailable - Create validation middleware (backend/src/middleware/marketValidation.js): * validateMarket() function with detailed error responses * rateLimitMarketCreation() middleware with Redis INCR * Specific error codes for each validation failure * Comprehensive inline documentation - Add Redis client utility (backend/src/utils/redis.js): * Connection handling with retry strategy * Event logging for monitoring * Graceful shutdown on SIGTERM - Update market creation endpoint (backend/src/routes/markets.js): * Apply validation and rate limiting middleware * Instant publishing without admin approval * Enhanced logging for permissionless markets * Structured error responses - Add comprehensive unit tests (>90% coverage target): * marketValidation.test.js: 50+ test cases for all validation rules * rateLimiting.test.js: 20+ test cases for rate limiting logic * Mock database and Redis for isolated testing * Edge cases and error handling covered - Add Redis to docker-compose.yml: * Redis 7 Alpine image * Persistent volume for data * Health check configuration * Port 6379 exposed - Update environment configuration: * Add REDIS_HOST, REDIS_PORT, REDIS_PASSWORD to .env.example * Document Redis configuration requirements - Add comprehensive documentation: * PERMISSIONLESS_LAUNCH_README.md: Complete guide (4000+ lines) - Detailed validation rules with examples - Rate limiting explanation - API usage with curl examples - Error response formats - Setup and configuration - Troubleshooting guide * PERMISSIONLESS_LAUNCH_QUICK_REFERENCE.md: Quick reference - Validation rules summary table - Error codes reference - Common commands - Testing checklist - Update main README.md: * Add permissionless market creation section * Link to detailed documentation * Update "How It Works" section - Add ioredis dependency to package.json Error codes implemented: - DESCRIPTION_TOO_SHORT (400): Question < 50 characters - INVALID_OUTCOME_COUNT (400): Not 2-5 outcomes - INVALID_END_DATE (400): Past date or > 1 year future - DUPLICATE_MARKET (409): Question already exists - RATE_LIMIT_EXCEEDED (429): 3 markets in 24 hours - MISSING_WALLET_ADDRESS (400): No wallet provided Features: - Instant market publishing without admin approval - Automated metadata verification on submission - Specific actionable error messages per validation failure - Rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) - Retry-After header when rate limit exceeded - Case-insensitive duplicate detection with whitespace trimming - Structured logging for all validation events - Redis connection resilience with fallback behavior Testing: - 70+ unit tests covering all validation scenarios - Edge cases: null values, empty strings, boundary conditions - Error handling: database errors, Redis failures - Rate limiting: multiple wallets, TTL expiration, header validation - Mock-based testing for isolation Closes Hahfyeex#164 * docs: add comprehensive PR summary for permissionless launch * test: add Taurus throughput stress test suite with CI integration - Implement comprehensive stress test suite with 3 scenarios: * 500 concurrent users placing bets (p95 < 2s, error rate < 1%) * 50 simultaneous market resolutions (p95 < 5s) * 1000 concurrent WebSocket connections (99%+ success rate) - Add Taurus configuration (stress-test.yml) with performance thresholds - Create Python test runner (run-stress-test.py) with dependency checks - Integrate stress tests into GitHub Actions CI pipeline - Add comprehensive documentation: * STRESS_TEST_README.md - Full testing guide (2000+ lines) * STRESS_TEST_BOTTLENECKS.md - Bottleneck analysis with fixes (1500+ lines) * STRESS_TEST_QUICK_REFERENCE.md - Quick command reference (500+ lines) * STRESS_TEST_PR_SUMMARY.md - PR summary and validation checklist - Document 8 identified bottlenecks with priority matrix: * P0: Database connection pool exhaustion, missing indexes, no rate limiting * P1: Synchronous operations, no caching, WebSocket limits * P2: Inefficient JSON parsing, unoptimized logging - Add Python dependencies (requirements.txt): bzt>=1.16.0, requests>=2.31.0 - Update README.md with stress testing section - Update .gitignore to exclude test results and Python artifacts Performance targets: - Throughput: 8-10 RPS baseline, 15-20 RPS after optimizations - p95 Latency: < 2000ms (< 5000ms for resolutions) - Error Rate: < 1% - Concurrent Users: 500+ supported CI/CD integration: - Runs on every PR to main/Default branches - Fails if performance thresholds exceeded - Uploads test results as artifacts - Includes cargo audit for Rust security checks Closes Hahfyeex#165 * feat: Add a `/status` endpoint, its corresponding unit tests, and API documentation. * feat: Implement WebSocket odds streaming and new image routes. * feat: implement paginated 'My Positions' endpoint with joined markets data and cursor-based pagination (Hahfyeex#160) * feat: Add a /status endpoint, its corresponding unit tests (Hahfyeex#159) * feat: Add 'Bet' event emission to the prediction market contract, introduce a worker to consume these events, and update .gitignore. (Hahfyeex#157) * feat: implement vault re-balancing with automated yield re-investment (Hahfyeex#168) - Add vault storage keys to DataKey enum: * VaultBalance: tracks total swept funds in Instance storage * ClaimDeadline(u64): records resolution timestamp per market * OriginalPayouts(u64): stores exact payout amounts for claimants * MarketSwept(u64): prevents double-sweeping - Implement sweep_unclaimed(market_id) function: * Callable only after 30 days (2,592,000 seconds) post-resolution * Checks each bet in market for unclaimed payouts * Respects settlement cursor (only sweeps unpaid winners) * Moves unclaimed funds to vault balance * Stores original payout amounts for future claims * Marks market as swept to prevent double-sweeping * Returns amount swept - Implement invest_vault() function: * Admin-only function for AMM re-investment * Placeholder for Stellar AMM integration * Validates vault has funds before investment * Returns amount invested * TODO: Actual AMM swap/deposit operations - Implement claim_original(market_id, claimant) function: * Allows winners to claim exact original payout anytime * Works even after vault sweep * Pays from vault balance if market swept * Prevents double-claiming by zeroing payout * Requires claimant authentication * Returns amount claimed - Add vault query functions: * get_vault_balance(): returns current vault balance * get_claim_deadline(market_id): returns resolution timestamp * is_market_swept(market_id): checks if market swept * get_original_payout(market_id, address): gets claimant's amount - Update resolve_market() to record claim deadline: * Stores resolution timestamp for 30-day tracking * Enables sweep_unclaimed deadline validation - Add comprehensive unit tests (30+ test cases): * Claim deadline recording on resolution * Vault balance initialization and tracking * 30-day deadline enforcement (before/at/after) * Sweep with various winner counts (0, 3, 5) * Settlement cursor respect (partial payments) * Double-sweep prevention * Original payout storage and retrieval * Claim after sweep functionality * Double-claim prevention * Multiple winners claiming * Vault balance decrease on claims * invest_vault validation * Edge cases: unresolved markets, non-winners, empty vault Test coverage: - Sweep logic: 10+ tests covering all scenarios - Claim logic: 8+ tests covering claim flows - Vault operations: 5+ tests for vault management - Edge cases: 7+ tests for error conditions - Total: 30+ tests achieving >90% coverage target Vault mechanics: - 30-day claim window before sweep eligibility - Original payouts tracked separately from yield - Claimants always get exact original amount - Vault balance managed independently - Settlement cursor respected (no double-payment) - Admin-controlled sweep and investment Security features: - Admin-only sweep and invest operations - Claimant authentication required for claims - Double-sweep prevention via MarketSwept flag - Double-claim prevention via payout zeroing - Vault balance validation before claims - 30-day deadline strictly enforced AMM integration (placeholder): - invest_vault() validates vault balance - TODO: Stellar AMM deposit operations - TODO: LP token tracking - TODO: Yield monitoring - Production implementation requires AMM client Inline documentation: - Comprehensive function comments - Vault re-balancing logic explained - Claimant protection mechanisms documented - AMM integration strategy outlined - 30-day deadline rationale provided - Storage key purposes clarified Closes Hahfyeex#162 * feat: implement Soroban TTL extension logic and maintenance worker script (Hahfyeex#163) * feat: implement Proposed outcome state machine (Issue Hahfyeex#24) (Hahfyeex#105) - Add MarketStatus enum (Open, Locked, Proposed, Resolved) - Add proposed_outcome and proposal_timestamp fields to Market struct - Add propose_result() with oracle auth and Locked state guard - Refactor resolve_market() with Proposed guard and 24h liveness window - Add lock_market() helper (Open -> Locked) - Add LIVENESS_WINDOW constant (86400s) - Add 10 tests covering state transitions, auth, and liveness boundary - Add docs/resolution-flow.md * * feat: implement Proposed outcome state machine (Issue Hahfyeex#24) - Add MarketStatus enum (Open, Locked, Proposed, Resolved) - Add proposed_outcome and proposal_timestamp fields to Market struct - Add propose_result() with oracle auth and Locked state guard - Refactor resolve_market() with Proposed guard and 24h liveness window - Add lock_market() helper (Open -> Locked) - Add LIVENESS_WINDOW constant (86400s) - Add 10 tests covering state transitions, auth, and liveness boundary - Add docs/resolution-flow.md * feat: implement Role-Based Access Control (Issue Hahfyeex#14) - Add access.rs: Role enum (Admin, Oracle, Resolver), ContractError, check_role/get_role/set_role helpers using persistent storage - Wire RBAC into all gated functions: Admin: initialize, assign_role, pause, set_market_params, create_market, lock_market Oracle: propose_result Resolver: resolve_market - Add assign_role() for admin-authorized key rotation - Add pause()/unpause() with assert_not_paused guard - Add set_market_params() for Admin to update Open market params - Remove single-admin DataKey::Admin and DataKey::OracleAddress in favour of persistent Role storage - Add 14 tests covering RBAC, pause, state machine, and boundaries - Add SECURITY.md with role hierarchy and function-role mapping * feat: implement emergency stop circuit breaker (Issue Hahfyeex#10) - Rename DataKey::Paused -> DataKey::IsPaused (persistent storage) - Add set_pause(admin, paused): admin-verified toggle with ContractPauseToggled event - Add panic_if_paused(): panics with exact message 'ContractPaused' - Add is_paused() -> bool: read-only query for frontend visibility - Add withdraw(): bettor stake withdrawal, gated by panic_if_paused - Gate place_bet and withdraw with panic_if_paused at function entry - Migrate IsPaused to persistent storage (survives ledger archival) - Add 8 circuit-breaker tests: toggle, non-admin rejection, normal ops, ContractPaused panics for place_bet and withdraw, event emission - Update README.md with Security Operations section * perf: refactor Soroban storage patterns for gas optimization (Hahfyeex#170) - Refactor Map<Address, (u32, i128)> to Vec<(Address, u32, i128)> for user positions - Remove Map import from soroban_sdk (no longer needed) Gas optimization rationale: - Map uses expensive key hashing operations for every access - Vec uses sequential access which is cheaper for small datasets - Typical prediction markets have <100 bettors - For n<100, Vec O(n) linear scan is faster than Map O(1) with hashing overhead - Estimated 30% gas cost reduction for typical market operations Functions refactored: 1. create_market(): Initialize positions as Vec instead of Map 2. place_bet(): Linear scan to find/update bettor position 3. batch_distribute(): Iterate through Vec instead of Map Storage pattern changes: - Before: Map<Address, (u32, i128)> - expensive hashing per operation - After: Vec<(Address, u32, i128)> - sequential access, no hashing Performance characteristics: - place_bet: O(n) scan vs O(1) Map.set, but cheaper for n<100 - batch_distribute: O(n) iteration vs O(n) Map.iter, but no hashing overhead - Memory: Vec is more compact than Map (no hash table overhead) Inline documentation: - Added gas optimization comments to all refactored functions - Explained Vec vs Map tradeoffs - Documented typical market size assumptions - Clarified performance characteristics All existing tests pass with Vec-based storage: - Market creation and initialization - Bet placement and position updates - Batch distribution and settlement - Edge cases and error conditions No behavioral changes: - Same functionality, different storage implementation - All assertions and validations unchanged - Event emissions unchanged - Settlement logic unchanged Closes Hahfyeex#156 * Hahfyeex#6 Admin Circuit Breaker (Emergency Pause) (Hahfyeex#108) * feat: implement Proposed outcome state machine (Issue Hahfyeex#24) - Add MarketStatus enum (Open, Locked, Proposed, Resolved) - Add proposed_outcome and proposal_timestamp fields to Market struct - Add propose_result() with oracle auth and Locked state guard - Refactor resolve_market() with Proposed guard and 24h liveness window - Add lock_market() helper (Open -> Locked) - Add LIVENESS_WINDOW constant (86400s) - Add 10 tests covering state transitions, auth, and liveness boundary - Add docs/resolution-flow.md * feat: implement Role-Based Access Control (Issue Hahfyeex#14) - Add access.rs: Role enum (Admin, Oracle, Resolver), ContractError, check_role/get_role/set_role helpers using persistent storage - Wire RBAC into all gated functions: Admin: initialize, assign_role, pause, set_market_params, create_market, lock_market Oracle: propose_result Resolver: resolve_market - Add assign_role() for admin-authorized key rotation - Add pause()/unpause() with assert_not_paused guard - Add set_market_params() for Admin to update Open market params - Remove single-admin DataKey::Admin and DataKey::OracleAddress in favour of persistent Role storage - Add 14 tests covering RBAC, pause, state machine, and boundaries - Add SECURITY.md with role hierarchy and function-role mapping * feat: implement emergency stop circuit breaker (Issue Hahfyeex#10) - Rename DataKey::Paused -> DataKey::IsPaused (persistent storage) - Add set_pause(admin, paused): admin-verified toggle with ContractPauseToggled event - Add panic_if_paused(): panics with exact message 'ContractPaused' - Add is_paused() -> bool: read-only query for frontend visibility - Add withdraw(): bettor stake withdrawal, gated by panic_if_paused - Gate place_bet and withdraw with panic_if_paused at function entry - Migrate IsPaused to persistent storage (survives ledger archival) - Add 8 circuit-breaker tests: toggle, non-admin rejection, normal ops, ContractPaused panics for place_bet and withdraw, event emission - Update README.md with Security Operations section * feat: admin circuit breaker toggle_pause (Issue Hahfyeex#6) - Rename set_pause -> toggle_pause(admin, setup_pause) per spec - Rename PauseToggled event symbol to match spec - All circuit breaker logic already in place from Issue Hahfyeex#10: DataKey::IsPaused in persistent storage panic_if_paused() panics with 'ContractPaused' is_paused() read-only query place_bet and withdraw gated by panic_if_paused Full test suite: toggle, non-admin rejection, normal ops, panic cases * feat: Implement oracle truth score calculation, API endpoints for oracle statistics, and dedicated truth and whale watcher workers. (Hahfyeex#173) Co-authored-by: folex1275 <soleyefolarin@gmail.com> * feat: Semgrep + Secret Scanning CI Pipeline (#<issue number>) (Hahfyeex#176) * feat: implement Firebase App Check for API protection (Hahfyeex#62) * feat: add Semgrep + secret scanning CI pipeline for security --------- Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com> * feat: implement Firebase App Check for API protection (Hahfyeex#62) (Hahfyeex#175) * feat: implement Firebase App Check for API protection (Hahfyeex#62) * feat: add Semgrep + secret scanning CI pipeline for security --------- Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com> * - Form Persistence (Hahfyeex#182) * feat: add WhatIfSimulator P&L projection panel - Add collapsible WhatIfSimulator component with Recharts BarChart - Stake input via range slider and number field kept in sync - Real-time updates via useEffect with 200ms debounce - Shows projected payout, P&L, and implied probability - Pure calc utility in simulatorCalc.ts with full inline docs - 100% test coverage on calculation logic (36 tests passing) - Integrated into MarketCard (desktop) and TradeDrawer (mobile) - README documents P&L formula and usage * feat: add BettingSlip batch betting drawer - BettingSlipContext: global queue state with addBet/removeBet/clearBets - WalletContext: lifts wallet state globally for layout-level access - useBatchTransaction: bundles bets into single Freighter XDR approval - BettingSlip: slide-up drawer (mobile) / fixed right panel (desktop) - Toast: queue-full warning when 6th bet attempted (max 5) - MarketCard: Add to Slip button alongside existing Bet button - layout.tsx: providers + BettingSlipWrapper mounted globally - page.tsx: migrated to useWalletContext - README: documents component usage, props, and batch flow * feat: add PoolOwnershipChart fractional ownership pie chart - poolOwnership.ts: pure transform — group bets by wallet, calc % share, group wallets below 1% into Others slice, with full inline comments - usePoolOwnership: fetches GET /api/markets/:id, subscribes to Socket.io oddsUpdate events and re-renders chart live on new bets - PoolOwnershipChart: Recharts PieChart with custom tooltip (wallet + XLM), design token slice colors, loading/error/empty states - MarketCard: PoolOwnershipChart mounted below pool info line - socket.io-client installed for live WebSocket updates - Unit tests for buildOwnershipSlices and abbreviateWallet (>90% coverage) - README documents API data structure and transformation pipeline * feat: add useFormPersistence hook for bet form state - useFormPersistence(marketId): persists outcomeIndex, amount, slippageTolerance to localStorage key stella_bet_form_{marketId} - Restores state on mount, re-hydrates when marketId changes - clearForm(): removes localStorage entry and resets fields to defaults - 300ms debounced writes to avoid thrashing on every keystroke - MarketCard: wired to persistence hook, clearForm on submit, slippage selector - TradeDrawer: wired to persistence hook, clearForm on submit, slippage selector - Both components have Clear form button for manual reset - Unit tests for storageKey, read/write/clear, and round-trip (>90% coverage) - README documents key format and how to clear state for testing --------- Co-authored-by: victorisiguzor874 <jamesberry87487.com> * - Share Pizza Chart (Hahfyeex#180) * feat: add WhatIfSimulator P&L projection panel - Add collapsible WhatIfSimulator component with Recharts BarChart - Stake input via range slider and number field kept in sync - Real-time updates via useEffect with 200ms debounce - Shows projected payout, P&L, and implied probability - Pure calc utility in simulatorCalc.ts with full inline docs - 100% test coverage on calculation logic (36 tests passing) - Integrated into MarketCard (desktop) and TradeDrawer (mobile) - README documents P&L formula and usage * feat: add BettingSlip batch betting drawer - BettingSlipContext: global queue state with addBet/removeBet/clearBets - WalletContext: lifts wallet state globally for layout-level access - useBatchTransaction: bundles bets into single Freighter XDR approval - BettingSlip: slide-up drawer (mobile) / fixed right panel (desktop) - Toast: queue-full warning when 6th bet attempted (max 5) - MarketCard: Add to Slip button alongside existing Bet button - layout.tsx: providers + BettingSlipWrapper mounted globally - page.tsx: migrated to useWalletContext - README: documents component usage, props, and batch flow * feat: add PoolOwnershipChart fractional ownership pie chart - poolOwnership.ts: pure transform — group bets by wallet, calc % share, group wallets below 1% into Others slice, with full inline comments - usePoolOwnership: fetches GET /api/markets/:id, subscribes to Socket.io oddsUpdate events and re-renders chart live on new bets - PoolOwnershipChart: Recharts PieChart with custom tooltip (wallet + XLM), design token slice colors, loading/error/empty states - MarketCard: PoolOwnershipChart mounted below pool info line - socket.io-client installed for live WebSocket updates - Unit tests for buildOwnershipSlices and abbreviateWallet (>90% coverage) - README documents API data structure and transformation pipeline --------- Co-authored-by: victorisiguzor874 <jamesberry87487.com> Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com> * feat: implement configurable market creation fee with burn/DAO routing (Hahfyeex#183) - Add FeeMode enum (Burn / Treasury) and DataKey variants CreationFee, FeeDestination, FeeModeConfig to contract storage - Add creator: Address param to create_market; charge fee via try_transfer before market is stored; abort with InsufficientFeeBalance on failure - Add update_fee(new_fee, new_destination, new_mode) admin function with admin auth guard — no redeployment needed to change fee config - Add get_fee_config() read-only helper returning (fee, dest, mode) - Emit FeeColl event on every successful fee collection for off-chain indexing - Add 7 unit tests covering: zero-fee, treasury routing, burn routing, insufficient balance abort, max fee, admin auth enforcement, fee reset - Add CREATION_FEE_README.md documenting parameters and DAO governance - Update README.md to reference creation fee and DAO governance docs Closes Hahfyeex#147 * Feat/contract attestation sep0157 (Hahfyeex#178) * feat: implement Firebase App Check for API protection (Hahfyeex#62) * feat: add Semgrep + secret scanning CI pipeline for security * feat: implement SEP-0157 contract source attestation workflow (Hahfyeex#65) --------- Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com> * Adaptive Betting Slip (Hahfyeex#179) * feat: add WhatIfSimulator P&L projection panel - Add collapsible WhatIfSimulator component with Recharts BarChart - Stake input via range slider and number field kept in sync - Real-time updates via useEffect with 200ms debounce - Shows projected payout, P&L, and implied probability - Pure calc utility in simulatorCalc.ts with full inline docs - 100% test coverage on calculation logic (36 tests passing) - Integrated into MarketCard (desktop) and TradeDrawer (mobile) - README documents P&L formula and usage * feat: add BettingSlip batch betting drawer - BettingSlipContext: global queue state with addBet/removeBet/clearBets - WalletContext: lifts wallet state globally for layout-level access - useBatchTransaction: bundles bets into single Freighter XDR approval - BettingSlip: slide-up drawer (mobile) / fixed right panel (desktop) - Toast: queue-full warning when 6th bet attempted (max 5) - MarketCard: Add to Slip button alongside existing Bet button - layout.tsx: providers + BettingSlipWrapper mounted globally - page.tsx: migrated to useWalletContext - README: documents component usage, props, and batch flow --------- Co-authored-by: victorisiguzor874 <jamesberry87487.com> * feat: add WhatIfSimulator P&L projection panel (Hahfyeex#177) - Add collapsible WhatIfSimulator component with Recharts BarChart - Stake input via range slider and number field kept in sync - Real-time updates via useEffect with 200ms debounce - Shows projected payout, P&L, and implied probability - Pure calc utility in simulatorCalc.ts with full inline docs - 100% test coverage on calculation logic (36 tests passing) - Integrated into MarketCard (desktop) and TradeDrawer (mobile) - README documents P&L formula and usage Co-authored-by: victorisiguzor874 <jamesberry87487.com> * Add Figma design links for issues 80, 82, and 85 (Hahfyeex#191) Co-authored-by: Your Name <your-email@example.com> * feat: implement event-driven liquidity bot hook system (Hahfyeex#185) * Add How It Works Onboarding mini-README with Figma link (Hahfyeex#188) * feat: replace spinners with CSS shimmer skeleton loading states (Hahfyeex#197) Implements comprehensive skeleton loading screens across the app: Components: - Base Skeleton component with CSS shimmer animation - MarketCardSkeleton matching exact card layout - ActivityFeedSkeleton for live activity feed - MetricsSkeletons for LP metrics overview CSS Animation: - GPU-accelerated shimmer using background-position - 1.5s smooth animation across all skeletons - Detailed inline comments explaining the effect - Zero cumulative layout shift (CLS) when content loads Testing: - 29 unit tests with 100% coverage - Tests verify layout consistency and CLS prevention - Tests ensure exact dimension matching Integration: - Replaced loading spinners in page.tsx markets grid - Integrated ActivityFeedSkeleton in LiveActivityFeed - Added proper loading state detection - min-height containers prevent CLS Documentation: - Comprehensive README with API documentation - Examples for creating new skeleton variants - Best practices and performance characteristics - CLS testing guidance and troubleshooting Replaced Patterns: - 'Loading...' text → skeleton screens - Spinners → CSS shimmer placeholders - No layout shifts during content swap Closes Hahfyeex#137 * feat: Stellar Council governance voting UI (Hahfyeex#83) (Hahfyeex#198) - Add /governance Council Dashboard (wallet + membership gated) - VotingCard with evidence-review gate before voting unlocks - QuorumTracker progress bar (24h window, auto-resolves at quorum) - useCouncilMember hook for wallet-based access control - Backend governance routes: council check, list disputes, cast vote - DB schema: governance_disputes + governance_votes tables - GOVERNANCE_VOTER_EXPERIENCE.md mini-README for PR * Feat/149 dynamic theming engine (Hahfyeex#260) * feat: replace spinners with CSS shimmer skeleton loading states Implements comprehensive skeleton loading screens across the app: Components: - Base Skeleton component with CSS shimmer animation - MarketCardSkeleton matching exact card layout - ActivityFeedSkeleton for live activity feed - MetricsSkeletons for LP metrics overview CSS Animation: - GPU-accelerated shimmer using background-position - 1.5s smooth animation across all skeletons - Detailed inline comments explaining the effect - Zero cumulative layout shift (CLS) when content loads Testing: - 29 unit tests with 100% coverage - Tests verify layout consistency and CLS prevention - Tests ensure exact dimension matching Integration: - Replaced loading spinners in page.tsx markets grid - Integrated ActivityFeedSkeleton in LiveActivityFeed - Added proper loading state detection - min-height containers prevent CLS Documentation: - Comprehensive README with API documentation - Examples for creating new skeleton variants - Best practices and performance characteristics - CLS testing guidance and troubleshooting Replaced Patterns: - 'Loading...' text → skeleton screens - Spinners → CSS shimmer placeholders - No layout shifts during content swap Closes Hahfyeex#137 * feat: implement CSS variable-based dark/light theme engine --------- Co-authored-by: macnelson9 <michaelofatu@gmail.com> * Merge pull request Hahfyeex#1 from Hahfyeex/Default (Hahfyeex#259) * Feat/144 contract error boundary (Hahfyeex#204) * feat: Stellar Council governance voting UI (Hahfyeex#83) - Add /governance Council Dashboard (wallet + membership gated) - VotingCard with evidence-review gate before voting unlocks - QuorumTracker progress bar (24h window, auto-resolves at quorum) - useCouncilMember hook for wallet-based access control - Backend governance routes: council check, list disputes, cast vote - DB schema: governance_disputes + governance_votes tables - GOVERNANCE_VOTER_EXPERIENCE.md mini-README for PR * feat: add automatic trustline checker and one-click setup Closes Hahfyeex#132 - hasTrustline(): checks Horizon balances[] for asset_code + asset_issuer - buildTrustlineXdr(): TransactionBuilder + Operation.changeTrust (testnet) - submitTrustlineTx(): submits signed XDR to Horizon - useTrustline hook: check → modal → sign → submit → resume bet flow - TrustlineModal: handles needs_trustline, signing, submitting, wallet_missing, horizon_error, error states - MarketCard: trustline check gates placeBet() for custom asset markets - Unit tests >90% coverage (hasTrustline all branches, edge cases) - TRUSTLINE_README.md: supported assets + full flow diagram * feat: add personalized market discovery cards with SVG illustrations Closes Hahfyeex#124 - marketDiscovery.ts: ranking algo score=(categoryMatches*2)+(vol24h/1000) - detectCategory(): keyword-based auto-detection for 5 categories - isMarketHot(): >20% hourly volume growth threshold - MarketDiscoveryCard: SVG illustration, category tag, pool, end date, Hot badge - MarketDiscoveryGrid: fetches markets + user activity, renders top 6 - hover-lift CSS: translateY(-4px) + shadow, desktop-only via hover:hover media query - Unit tests >90% coverage (detectCategory, isMarketHot, rankMarkets all branches) - Wired into homepage above Open Markets section - MARKET_DISCOVERY_README.md: algorithm docs + how to add new categories * feat: add contract error boundary with user-friendly messages Closes Hahfyeex#134 - contractErrors.ts: 13 error codes mapped (5+ Soroban, Horizon, Freighter) - contractErrorSlice.ts: Redux slice with setContractError/clearContractError - store/index.ts: Redux store with contractError reducer - monitoring.ts: Sentry wrapper (logContractError with scope/tags/user) - ContractErrorBoundary: class component, getDerivedStateFromError, componentDidCatch dispatches Redux + logs Sentry, Retry resets state - withContractErrorBoundary HOC for convenience wrapping - ReduxProvider: client component wrapping app in Redux Provider - layout.tsx: ReduxProvider added at root - MarketCard + BettingSlip wrapped with ContractErrorBoundary - Unit tests >90% coverage: boundary render, retry, Redux dispatch, non-retryable, all mapContractError branches, slice actions - CONTRACT_ERROR_BOUNDARY_README.md: how to add new error codes * Feat/142 trustline auto checker (Hahfyeex#199) * feat: Stellar Council governance voting UI (Hahfyeex#83) - Add /governance Council Dashboard (wallet + membership gated) - VotingCard with evidence-review gate before voting unlocks - QuorumTracker progress bar (24h window, auto-resolves at quorum) - useCouncilMember hook for wallet-based access control - Backend governance routes: council check, list disputes, cast vote - DB schema: governance_disputes + governance_votes tables - GOVERNANCE_VOTER_EXPERIENCE.md mini-README for PR * feat: add automatic trustline checker and one-click setup Closes Hahfyeex#132 - hasTrustline(): checks Horizon balances[] for asset_code + asset_issuer - buildTrustlineXdr(): TransactionBuilder + Operation.changeTrust (testnet) - submitTrustlineTx(): submits signed XDR to Horizon - useTrustline hook: check → modal → sign → submit → resume bet flow - TrustlineModal: handles needs_trustline, signing, submitting, wallet_missing, horizon_error, error states - MarketCard: trustline check gates placeBet() for custom asset markets - Unit tests >90% coverage (hasTrustline all branches, edge cases) - TRUSTLINE_README.md: supported assets + full flow diagram --------- Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com> * feat: implement Freighter SDK atomic transaction batching - Rewrite useBatchTransaction with TransactionBuilder atomic bundling - Single Freighter pop-up for N operations (placeBet+trustline, placeBet+fee) - Per-operation error parsing: identifies which op failed by name - Clean atomic rollback on failure — no partial on-chain state - Add submitOperations() for explicit BatchOperation[] flows - Wire useBatchTransaction into LPDepositModal (deposit+trustline batch) - 16 unit tests, 98.33% statement coverage, 90%+ all metrics - Update jest.config.js to track useBatchTransaction coverage - Update README with hook API, batch flows, testnet instructions Closes Hahfyeex#126 * feat: implement client-side slippage protection with BigInt math - Add slippageCalc.ts: toStroops, calcPayoutStroops, isSlippageExceeded, stroopsToXlm - All payout calculations use pure BigInt (zero floating-point operations) - XLM 7-decimal precision preserved via stroop scaling (1 XLM = 1e7 stroops) - Add useSlippageGuard hook: snapshots odds at form-open via useRef, checks drift before submit - Add SlippageSettings component: 4 presets (0.5%, 1%, 2%, custom) + localStorage persistence - Preference key: stella_slippage_pref, restores on next visit - Add SlippageWarningModal: shows expected vs current payout with Proceed/Cancel - Wire into MarketCard: snapshot on outcome select, check before submitBet - 48 unit tests, 100% coverage on slippageCalc.ts - Update jest.config.js to track slippageCalc.ts coverage - README documents slippage calculation methodology Closes Hahfyeex#128 * chore: update package-lock --------- Co-authored-by: nafiuishaaq <nafiuig@gmail.com> Co-authored-by: Akpolo Ogagaoghene Prince <104951733+ogazboiz@users.noreply.github.com> Co-authored-by: Damidesign <damidolowo@gmail.com> Co-authored-by: you@christopherdominic <chriseze0@gmail.com> Co-authored-by: OpadijoIdris <Opadijoayomipo@gmail.com> Co-authored-by: Harold John <bossharoldjohn@gmail.com> Co-authored-by: afurious <misraisiguzor@gmail.com> Co-authored-by: Bamford <bamfordjnr5@gmail.com> Co-authored-by: Emmyt24 <lateeftosin1999@gmail.com> Co-authored-by: temma02 <tosinemma002@gmail.com> Co-authored-by: folex1275 <soleyefolarin@gmail.com> Co-authored-by: Lateef Tosin <65298603+Emmyt24@users.noreply.github.com> Co-authored-by: Afolarinwa Soleye <130229011+Folex1275@users.noreply.github.com> Co-authored-by: Ejirowebfi <ejirowebfi@gmail.com> Co-authored-by: Shredder401k <triplejgotthatstrap@gmail.com> Co-authored-by: Aboogeeky <Idrishassan35@gmail.com> Co-authored-by: Hahfyeez <36053600+Hahfyeex@users.noreply.github.com> Co-authored-by: hman <hman38705@gmail.com> Co-authored-by: summer-0ma <summerenyi@gmail.com> Co-authored-by: Ademola Adegbolu <officialblaqcypher1@gmail.com> Co-authored-by: Your Name <your-email@example.com> Co-authored-by: Daniel Odinegun <107105251+Danielodingz@users.noreply.github.com> Co-authored-by: Darkdante9 <ofatuuche2018@yahoo.com> Co-authored-by: Greedy_Biggie <99267251+Austinaminu2@users.noreply.github.com> Co-authored-by: macnelson9 <michaelofatu@gmail.com> Co-authored-by: Sunday Abel <abel123sunday@gmail.com> Co-authored-by: Mac-5 <emmapiusmark@gmail.com>
…upport (Hahfyeex#577) - Add RateLimitError class thrown on HTTP 429 with retry-after value - Add x-cg-demo-api-key header when COINGECKO_API_KEY env var is set - Add request counter that warns when approaching free-tier rate limit - Catch RateLimitError in resolveMarket and retry after server-specified delay - Add COINGECKO_API_KEY to .env.example
* feat: add gzip response compression with 1KB threshold (Hahfyeex#498) - Add compression npm package to backend/package.json - Inject compression middleware before all routes in index.js with threshold: 1024 - Add integration tests verifying gzip applied for >1KB and skipped for <1KB payloads - Remove pre-existing duplicate route declarations in index.js * feat: add hourly stale-market expiry cron job - Add jobs/expireMarkets.js: queries unresolved markets past end_date by more than 2 hours (grace period) and sets status = 'EXPIRED' - Log every auto-expired market_id and question - Persist expired entries to expired_markets_digest table for daily admin digest (getDailyDigest helper included) - Wire job into index.js alongside existing resolver cron - Update GET /api/markets to exclude EXPIRED markets from active list (both plain and category-filtered queries) - Add migration 012_expired_markets_digest.sql - Add unit tests (6 passing) with injectable clock; verify grace period boundary: NOW-1h NOT expired, NOW-2h1m IS expired
…Hahfyeex#566) - Add compression npm package to backend/package.json - Inject compression middleware before all routes in index.js with threshold: 1024 - Add integration tests verifying gzip applied for >1KB and skipped for <1KB payloads - Remove pre-existing duplicate route declarations in index.js
…g/error states (Hahfyeex#579) Co-authored-by: afurious <misraisiguzor@gmail.com>
* Add GET /api/bets/export endpoint with JWT auth and wallet ownership check * Export bets as CSV with date, market, outcome, stake, payout, net gain/loss, tx hash * Calculate payouts for winners, handle cancelled bets as refunds * Add transaction_hash column to bets table * Closes Hahfyeex#613 feat: implement market watchlist with localStorage persistence * Add useWatchlist hook for managing watched markets in localStorage * Add bookmark icon to market cards with toggle functionality * Add Watchlist tab to markets list with badge count * Filter markets by watchlist in tab view * Closes Hahfyeex#603 feat: connect pull-to-refresh to mobile markets list * Wrap mobile page content with PullToRefresh component * Trigger React Query invalidation on 60px pull from top * Add haptic feedback on refresh trigger * Closes Hahfyeex#599 feat: implement MobileShell layout wrapper with safe areas * Add safe area insets for top and bottom using CSS env() * Set meta theme-color to match app theme * Apply overscroll-behavior: contain to prevent scroll chaining * Add scroll restoration hook for page navigation * Closes Hahfyeex#602
…ion (closes Hahfyeex#580 Hahfyeex#611 Hahfyeex#605 Hahfyeex#607)\n\n- Hahfyeex#580: added markets.fee_rate_bps, used in payoutService BigInt arithmetic path, removed hardcoded 3%\n- Hahfyeex#611: added memo validation/storage in bets route, Horizon memo verification, include memo in responses\n- Hahfyeex#605: added market detail JSON-LD event structured data, canonical + hreflang, metadata tests\n- Hahfyeex#607: added /api/anchor routes for info/deposit/transactions and docs/anchor-integration.md\n (Hahfyeex#618)
… UI (closes Hahfyeex#557, closes Hahfyeex#587, closes Hahfyeex#591) - Hahfyeex#591: Add BetSlipSummary component with full-screen overlay, plain-language bet details, slippage warning, stroop-integer amounts, and unit tests - Hahfyeex#587: Add oracle circuit breaker with consecutive failure counter, admin alert at 3 failures, interval pause at 10 failures, and health ping endpoint - Hahfyeex#557: Dispute submission UI with DisputeModal, reason validation (50 chars), evidence URL field, DisputeStatusTracker, and duplicate prevention
|
@Fahmedo Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #557, Closes #587, Closes #591
#591 — Bet Slip Summary Before Freighter Signing
BetSlipSummarycomponent as a full-screen overlay#587 — Oracle Circuit Breaker for Silent Backend Failures
runOraclecycleGET /api/health/oracleendpoint pinged before each cycle to verify backend connectivity#557 — Dispute Submission UI for Market Outcomes
DisputeModalwith reason textarea (min 50 chars enforced), optional evidence URL fieldPOST /api/markets/:id/disputeon submissionDisputeStatusTrackershows Submitted → Under Review → Resolved steps